#region Usings
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Web;
using BK.BaseEntities;
using BK.BL;
using Lib.Data.CriteriaRoutine;
using Lib.Data.ORM.Entity;
using Lib.Data.ORM.EntityManagement;
using Lib.General;
using Lib.Utils.WebUtils;
#endregion

namespace BK.WebSite.Accounting.Autocomplete
{
	public abstract class BaseAutocompleteHandler<TEntity, TDataView> : IHttpHandler
		where TEntity : BaseBkEntity, new()
		where TDataView : BaseDataView<TEntity, IdentifierInt>
	{
		#region Instance Methods
		protected abstract AutocompleteEntity[] DoConvertEntities(TEntity[] entities);

		protected virtual Criteria CreateCriteria()
		{
			return new Criteria(PropertyNameToBeFiltered, Clause.Like, string.Format("%{0}%", SearchToken));
		}

		protected virtual void DoBuildResponse(AutocompleteEntity[] entities, StringBuilder stringBuilder)
		{
			DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof (AutocompleteEntity[]));
			using (MemoryStream stream = new MemoryStream())
			{
				serializer.WriteObject(stream, entities);

				stream.Position = 0;
				StreamReader streamReader = new StreamReader(stream);
				stringBuilder.Append(streamReader.ReadToEnd());
			}
		}

		protected string BuildRow(string displayName, object value)
		{
			return string.Format("{0}|{1}", displayName, value);
		}

		protected TEntity[] DoGetEntities()
		{
			return ((TDataView) BlContext.Instance.GetEntityView<TEntity>()).Load(CreateCriteria());
		}
		#endregion

		#region Instance Properties
		protected virtual string PropertyNameToBeFiltered
		{
			get { return "Name"; }
		}

		protected IDataView DataView
		{
			get { return (IDataView) BlContext.Instance.DataManagers[typeof (TEntity)]; }
		}

		protected string SearchToken
		{
			get { return RequestManager.GetString("name_contains", null); }
		}
		#endregion

		#region IHttpHandler Members
		public void ProcessRequest(HttpContext context)
		{
			Logger.Info(GetType(), context.Request.RawUrl);

			TEntity[] entities = DoGetEntities();
			AutocompleteEntity[] autocompleteEntities = DoConvertEntities(entities);

			context.Response.ContentType = "application/json;charset=UTF-8";
			StringBuilder stringBuilder = new StringBuilder();

			DoBuildResponse(autocompleteEntities, stringBuilder);

			context.Response.Write(stringBuilder.ToString());
			context.Response.End();
		}

		public bool IsReusable
		{
			get { return false; }
		}
		#endregion
	}
}